package com.sww.pj.common.aspect;

import java.lang.reflect.Method;
import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sww.pj.common.annotation.RequiredLog;
import com.sww.pj.common.utils.IPUtils;
import com.sww.pj.common.utils.ShiroUtils;
import com.sww.pj.sys.pojo.SwwLog;
import com.sww.pj.sys.service.SwwLogService;

import lombok.extern.slf4j.Slf4j;

@Aspect

@Slf4j

@Component

public class SwwLogAspect {
	@Pointcut("@annotation(com.sww.pj.common.annotation.RequiredLog)")
	public void logPointCut() {}
	
	
	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint jp)
			throws Throwable{
		try {
			long t1=System.currentTimeMillis();
			Object result=jp.proceed();
			long t2=System.currentTimeMillis();
			//将用户信息写入到数据库
			saveLog(jp,(t2-t1));
			return result;
		}catch(Throwable e) {
			log.error("after:{}",e.getMessage());
			throw e;
		}
	}
	
	
	
@Autowired
	private SwwLogService swwLogService;

    private void saveLog(ProceedingJoinPoint jp,long time) throws Throwable{
   	 //1.获取用户行为日志
		 //1.1获取ip地址
		 String ip=IPUtils.getIpAddr();
		 String username=ShiroUtils.getUsername();
		 Class<?> targetCls=jp.getTarget().getClass();
		 //1.3.2获取目标方法
		 MethodSignature ms=(MethodSignature)jp.getSignature();
		 String methodName=ms.getName();
		 Method targetMethod=targetCls.getMethod(methodName, ms.getParameterTypes());
		 //1.3.3获取目标方法上的注解
		 RequiredLog requiredLog=targetMethod.getAnnotation(RequiredLog.class);
		 //1.3.4获取RequiredLog注解中定义的value属性值
		 String operation="operation";
		 if(requiredLog!=null) {//假如是切入点表示是注解方式则不需要再做判断.
			 operation=requiredLog.value();
		 }
		 //1.4获取目标方法信息(类全名+方法名)
		 String method=targetCls.getName()+"."+methodName;
		 //1.5获取方法执行时传入的实际参数
		 //String params=Arrays.toString(jp.getArgs());//转普通串
		 String params=new ObjectMapper().writeValueAsString(jp.getArgs());
		 //2.封装用户行为日志
    	SwwLog log=new SwwLog();
    	log.setIp(ip);
    	log.setUsername(username);
    	log.setMethod(method);
    	log.setOperation(operation);
    	log.setParams(params);
    	log.setTime(time);
    	log.setCreatedTime(new Date());
    	
    	//3.储存
    	swwLogService.saveObject(log);
    }
	
	
}